# coding=utf-8
# Copyright 2024 The Google Research Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# -*- coding: utf-8 -*-
"""hamming78.ipynb

Automatically generated by Colaboratory.

Original file is located at
    https://colab.research.google.com/drive/1cNuh89V1YkcywJ10GlZYiHMfvU8G4jcS?resourcekey=0-hwsaGIbifAwqEAvg3wuNfg

Copyright 2021 Google LLC

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    https://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

## Numerical Evidence for claims presented in the article:
### "From Binary Error Correcting Codes to a Relation Between Maximal D=4 and D=3 Supergravities"
"""

#@title Initialization (Simply run this cell to use the default library)
reset_library = True #@param {type:"boolean"}
m_theory_library_url = "https://github.com/google-research/google-research/trunk/m_theory" #@param {type:"string"}
m_theory_library_source = "Embedded Version" #@param ["Embedded Version", "Upload from Computer", "Fetch from Repository"]

import glob
import os
import shlex
import shutil
import subprocess
import time


def _get_embedded_archive(filename='m_theory.zip'):
  import base64
  archive = b'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'
  with open(filename, 'wb') as h_out:
    h_out.write(base64.b64decode(archive))
  subprocess.call(['unzip', filename])


def _get_archive_via_upload(filename='m_theory.zip'):
  from google.colab import files
  while True:
    print('Please upload', filename)
    uploaded = files.upload()
    print('Uploaded:', {k: len(v) for k, v in uploaded.items()})
    if filename in uploaded:
      break
  subprocess.call(['unzip', filename])


def _get_archive_from_repository(url=None):
  import os
  import shlex
  if url is None:
    url = m_theory_library_url
  os.system('[ -f /usr/bin/svn ] || apt install subversion')  # Subshell!
  subprocess.run(['/usr/bin/svn', 'export', url])

###
for filename in glob.glob('*.zip'):
  print('Removing:', filename)
  os.unlink(filename)

if reset_library:
  try:
    shutil.rmtree('m_theory')
  except OSError:
    pass

while not os.access('m_theory', os.X_OK):
  time.sleep(0.5)  # If something goes wrong here, do not fast-loop-on-failure.
  print('Obtaining package...')
  if m_theory_library_source.startswith('Embedded '):
    _get_embedded_archive()
  elif m_theory_library_source.startswith('Upload '):
    _get_archive_via_upload()
  elif m_theory_library_source.startswith('Fetch '):
    _get_archive_from_repository(m_theory_library_url)
  else:
    print('Mangled m_theory_library_source, aborting.')
    break

if os.access('m_theory', os.X_OK):
  print('Archive is available.')
  # Symlink things upwards into the current directory.
  for filename in sorted(os.listdir('m_theory')):
    try:
      os.symlink(os.path.join('m_theory', filename), filename)
    except OSError:
      pass

#@title General Definitions ("Right-Click -> Form -> Show Code" to show/hide)

# Adjusting import path
import os
import sys
m_theory_path = os.path.join(os.getcwd(), 'm_theory')
if m_theory_path not in sys.path: sys.path.append(m_theory_path)


from dim3.so8xso8.src import analysis as analysis8
from dim4.so8.src import analysis as analysis7

from m_theory_lib import algebra
from m_theory_lib import m_util as mu

import itertools

import numpy
import tensorflow as tf


e7 = algebra.g.e7
e8 = algebra.g.e8
sugra7c = analysis7.SO8_SUGRA()
sugra8 = analysis8.SO8xSO8_SUGRA()


# Names are mostly aligned with the mathematics even where this violates PEP-8.
# pylint:disable=invalid-name


def printpoly(monomials, coeffs, eps=1e-6):
  """Prints polynomial coefficients."""
  coeffs = numpy.asarray(coeffs)
  coeffs_c = coeffs.reshape(2, -1).T.dot([1, 1j])
  rows = []
  for mm, p in zip(monomials, coeffs_c):
    if abs(p) < eps:
      continue
    rows.append(
        (''.join(str(n + 1) for n, power in enumerate(mm) if power == 1),
         numpy.array(p).round(8)[()]))
  print(''.join(repr(row) + '\n'
                for row in sorted(rows,
                                  key=lambda sc: (-len(sc[0]), sc[0]))))


def v14_from_7z(zs):
  """Maps complex SL2x7 coordinates to the corresponding 14-vector."""
  cs = numpy.array([0.25 * mu.undiskify(z) for z in zs])
  return numpy.concatenate([cs.real, cs.imag], axis=0)


def v70_from_7z(zs):
  """Maps complex SL2x7 coordinates to the corresponding E7 70-vector."""
  return e7.sl2x7[:2, :, :70].reshape(-1, 70).T.dot(v14_from_7z(zs))


def get_v128_from_v70():
  """Returns the [128, 70]-ndarray mapping an E7 v70 to an E8 v128."""
  v128_from_v70_expanded = numpy.zeros([2, 8, 8, 2, 35])
  for sc in (0, 1):
    for d in range(7):
      v128_from_v70_expanded[sc, d, d, sc, d] += 1.0
      v128_from_v70_expanded[sc, d + 1, d + 1, sc, d] += -1.0
    for ij, (i, j) in enumerate(algebra.g.su8.ij_map):
      v128_from_v70_expanded[sc, i, j, sc, 7 + ij] += 1.0
      v128_from_v70_expanded[sc, j, i, sc, 7 + ij] += 1.0
  return v128_from_v70_expanded.reshape(128, 70)


v128_from_v70 = get_v128_from_v70()


hamming844_words = (
    '',
    '1248', '1578', '1368', '2358', '2678', '3478', '4568',
    '1237', '1256', '1467', '3567', '2457', '1345', '2346',
    '12345678')
hamming844_terms = [tuple(int(d) - 1 for d in word)
                    for word in hamming844_words]
hamming844_mask = numpy.stack(
    [[x in term for x in range(8)] for term in hamming844_terms],
    axis=0)
hamming743_mask = hamming844_mask[:, :7]


def w_hamming8(zs):
  """Returns the holomorphic (8,4,4)-Hamming Superpotential."""
  return sum(zs[sel].prod() for sel in hamming844_mask)


def w_hamming7c(zs, omega=0):
  """Returns the omega-deformed (7,4,3)-Hamming Superpotential."""
  # We multiply all z8-containing terms with exp(-2jw) and then
  # all terms with exp(jw).
  return w_hamming8(
      numpy.concatenate([zs, [numpy.exp(-2j * omega)]], axis=0)
      ) * numpy.exp(1j * omega)


def get_tf_pot78c_stat78c(s88=0.0, c88=0.0, squash=False, verbose=False):
  """Returns (dyonic_potential_func, dyonic_stationarity_func) TF functions."""
  v128_sc = numpy.stack([numpy.eye(8) * s88, numpy.eye(8) * c88],
                        axis=0).reshape(-1)
  scale = sugra8.potential_and_stationarity(v128_sc)[0] / (-6)
  if verbose:
    print(f'scale={scale}')
  tc_v128_sc = mu.tff64(v128_sc)
  tc_v128_from_v70 = mu.tff64(v128_from_v70)
  tc_scale = mu.tff64(scale)
  def tf_pot78c(t_v70):
    t_v128 = tc_v128_sc + tf.einsum('ea,a->e', tc_v128_from_v70, t_v70)
    t_pot, *_, t_stat = sugra8.tf_ext_sugra_tensors(t_v128)
    if verbose:
      print(f'[E8] t_pot={t_pot.numpy():.12f} t_stat={t_stat.numpy():.12g}')
    return t_pot / tc_scale
  tf_grad_pot78c = mu.tf_grad(tf_pot78c)
  def tf_stat78c(t_v70):
    t_pot = tf_pot78c(t_v70)
    t_grad = tf_grad_pot78c(t_v70)
    t_stat = tf.math.reduce_sum(tf.math.square(t_grad))
    if verbose:
      print(f'[E7] t_pot={t_pot.numpy():.12f} t_stat={t_stat.numpy():.12g}')
    return tf.math.asinh(t_stat) if squash else t_stat
  return tf_pot78c, tf_stat78c


### Superpotentials for sugra7c and sugra8 ###

# Our embedding of SL(2)x7 is such that the superpotential can be read off
# of A1 along this direction.
sugra7_dir_A1 = numpy.array([0.0, 0.0, 1.0] + [0.0] * 5)


def sugra7c_holomorphic_superpotential(zs, omega=0):
  """The holomorphic superpotential for dyonic-SO(8) supergravity."""
  zs = numpy.asarray(zs)
  v70 = v70_from_7z(zs)
  t_vielbein = sugra7c.tf_vielbein(mu.tff64(v70))
  # The definitions in this m_theory library differ from
  # https://arxiv.org/abs/1302.6219 by omega -> -omega,
  # which we here fix by providing -omega:
  t_T = sugra7c.tf_T(t_vielbein, t_omega=mu.tff64(-omega))
  ts_A123 = sugra7c.tf_A123(t_T, want_A1=True, want_A2=False, want_A3=False)
  t_A1, *_ = ts_A123
  A1 = t_A1.numpy()
  W = sugra7_dir_A1.dot(A1.dot(sugra7_dir_A1))
  kaehler_factor = numpy.sqrt((1 - zs * zs.conjugate()).prod())
  return W * kaehler_factor


sugra8_dir_A1 = numpy.array([0.0] * 15 + [1.0])


def embed_70_2_in_128(v70, s, c):
  """The linear embedding function E(v70, s, c) from the paper."""
  return 2 * (v128_from_v70.dot(v70) - 0.5 *
              numpy.stack([numpy.eye(8) * s,
                           numpy.eye(8) * c],
                          axis=0).ravel())


def sugra8_holomorphic_superpotential(zs):
  """The holomorphic superpotential for SO(8)xSO(8) supergravity."""
  zs = numpy.asarray(zs)
  v70 = v70_from_7z(zs[:7])
  c8 = 0.25 * mu.undiskify(zs[-1])
  v128 = embed_70_2_in_128(v70, c8.real, c8.imag)
  t_vielbein = sugra8.tf_vielbein(mu.tff64(v128))
  t_pot, t_T, t_A1, t_A2 = sugra8.tf_sugra_tensors_from_vielbein_batched(
      t_vielbein)
  del t_pot, t_T, t_A2  # Unused, named for documentation only.
  A1 = t_A1.numpy()
  W = sugra8_dir_A1.dot(A1.dot(sugra8_dir_A1))
  kaehler_factor = numpy.sqrt((1 - zs * zs.conjugate()).prod())
  return W * kaehler_factor

#@title Code for claims 1,2,4

# Monomials and points for mapping out the (7,4,3)-Hamming potential.
# We assume that we will have max power 1, but have to validate
# that later.
h7_monomials = numpy.array(list(itertools.product(*[[0.0, 1.0]]*7)))
h7_zs = numpy.array(list(itertools.product(*[[-0.1, 0.2]]*7)))


# Likewise for the (8,4,4)-Hamming potential.
h8_monomials = numpy.array(list(itertools.product(*[[0.0, 1.0]]*8)))
h8_zs = numpy.array(
    list(itertools.product(*[[-0.15, 0.17]]*8)))


def check_superpotential_h7c(omega=0.0, num_spot_checks=20, seed=0,
                             verbose=True):
  """Checks that the (7,4,3)-polynomial matches the D=4 superpotential."""
  h7_ys = numpy.array([
      sugra7c_holomorphic_superpotential(zs, omega)
      for zs in h7_zs])
  h7_residuals, h7_coeffs, f_fit_h7 = mu.polyfit(
      h7_monomials, h7_zs, h7_ys)
  assert abs(h7_residuals) < 1e-10
  if omega == 0:
    # All coeffs need to be ~0 or ~1 at omega==0.
    assert set(h7_coeffs.round(5)) <= {0.0, 1.0}
  #
  print(f'### Polynomial Coefficients for (7,4,3), omega={omega:.8f}, '
        f'cos(omega)={numpy.cos(omega):.8f}, '
        f'sin(omega)={numpy.sin(omega):.8f} ###')
  printpoly(h7_monomials, h7_coeffs)
  #
  random_z7s = mu.rng(seed).normal(size=[num_spot_checks, 7, 2],
                                   scale=0.1).dot([1, 1j])
  for rz7s in random_z7s:
    predicted = f_fit_h7(rz7s)
    target = w_hamming7c(rz7s, omega)
    if verbose:
      ptd = numpy.array([predicted, target, abs((predicted-target) / target)])
      print(f'[predicted, target, delta] = {ptd.round(8).tolist()}')
    assert abs(predicted - target) < 1e-10, f'Deviation: {predicted-target:.6g}'
  # If we reached this point without tripping over any `assert` checks,
  # everything is good.
  print('\n### All checks succeeded. ###\n')
  #
  return h7_coeffs, f_fit_h7


def check_superpotential_h8(num_spot_checks=20, seed=0,
                            verbose=True):
  """Checks that the (8,4,4)-polynomial matches the D=3 superpotential."""
  h8_ys = numpy.array([
      sugra8_holomorphic_superpotential(zs)
      for zs in h8_zs])
  h8_residuals, h8_coeffs, f_fit_h8 = mu.polyfit(
      h8_monomials, h8_zs, h8_ys)
  assert abs(h8_residuals) < 1e-10
  assert set(h8_coeffs.round(5)) <= {0.0, 1.0}  # All 0 or 1.
  #
  print('### Polynomial Coefficients for (8,4,4) ###')
  printpoly(h8_monomials, h8_coeffs)
  #
  random_z8s = mu.rng(seed).normal(size=[num_spot_checks, 8, 2],
                                   scale=0.2).dot([1, 1j])
  for rz8s in random_z8s:
    predicted = f_fit_h8(rz8s)
    target = w_hamming8(rz8s)
    if verbose:
      ptd = numpy.array([predicted, target, abs((predicted-target) / target)])
      print(f'[predicted, target, delta] = {ptd.round(8).tolist()}')
    assert abs(predicted - target) < 1e-6
  # If we reached this point without tripping over any `assert` checks,
  # everything is good.
  print('\n### All checks succeeded. ###\n')
  return h8_coeffs, f_fit_h8


def do_validate_claim1(verbose=False):
  """Validates Claim #1."""
  print('\n\n ### C#1: Validating SO(8) superpotential claim. ###\n\n')
  # Set `verbose=True` for more detail.
  check_superpotential_h7c(omega=0, verbose=verbose)


def do_validate_claim2(verbose=False):
  """Validates Claim #2."""
  print('\n\n### C#2: Validating SO(8)xSO(8) superpotential claim. ###\n\n')
  check_superpotential_h8(verbose=verbose)


def do_validate_claim4(verbose=False,
                       angles=(0.01, 0.125, 0.2345, -5.678)):
  """Validates Claim #4."""
  print('\n\n ### C#4: Validating SO(8)c superpotential claim. ###\n\n')
  for angle in angles:
    check_superpotential_h7c(omega=numpy.pi*angle, verbose=verbose)

#@title Code for claim 3

# For each 8-bit number, we want to know how many 1-bits it contains.
num_bits_set = numpy.array(
    # [2:] strips the '0b'-prefix.
    [sum(map(int, bin(x)[2:])) for x in range(256)])


# We encode the Spin(16)-roots as 8-bit numbers,
# where +1/2 is represented by a 1-bit and -1/2 by a 0-bit,
# the 'leading' bit (that determines whether a root is positive)
# has weight 128, and the 'final' bit has weight 1.
# We are only interested in positive roots,

e8_spin16_pos_roots = [
    x for x in range(128, 256) if num_bits_set[x] % 2 == 0]


def admissible_root(pos_roots_picked, r_cand):
  """Returns True iff a root is admissible."""
  # An admissible positive root
  # - is not among the already picked roots
  #   (i.e. number of bits different from a picked root
  #   is never zero).
  # - does not have exactly 2 bits in common
  #   (i.e. 6 bits different) with any picked root.
  # - does not have exactly 2 bits in common with
  #   the negative root associated with a picked positive root
  # - (since it is a positive root, it cannot be among the
  #    negative roots)
  return (all(num_bits_set[r_cand ^ r_picked] not in (0, 6)
              for r_picked in pos_roots_picked) and
          all(num_bits_set[r_cand ^ (0xff - r_picked)] != 6
              for r_picked in pos_roots_picked))


def commuting_sl2_root_collections(start_root=0b11111111):
  """Yields root-collections that correspond to eight commuting SL(2)s."""
  pos_roots_picked = [start_root]
  num_pos_roots_picked = 1
  nth_root_candidates = [[] for _ in range(9)]
  nth_root_candidates[1] = [
      r_cand for r_cand in e8_spin16_pos_roots
      if admissible_root(pos_roots_picked, r_cand)]
  while num_pos_roots_picked:
    if num_pos_roots_picked == 8:
      yield tuple(bin(0x100 + x)[-8:] for x in pos_roots_picked)
      num_pos_roots_picked -= 1
      pos_roots_picked.pop()
    remaining_candidates = nth_root_candidates[num_pos_roots_picked]
    while remaining_candidates:
      pos_roots_picked.append(remaining_candidates.pop())
      num_pos_roots_picked += 1
      nth_root_candidates[num_pos_roots_picked][:] = (
          r_cand for r_cand in nth_root_candidates[num_pos_roots_picked - 1]
          if admissible_root(pos_roots_picked, r_cand))
      break
    else:  # while-else!
      # no more candidates with num_pos_roots_picked. Try one less.
      num_pos_roots_picked -= 1
      pos_roots_picked.pop()


def hamming_distances(roots):
  """Computes Hamming distances for a root-set.

  Args:
    roots: Sequence of bit-strings, each of the form "00001111".

  Returns:
    Hamming distance statistics, as a sequence of (hamming_distance, num_pairs).
  """
  s01 = str.maketrans('01', '10')
  pos_neg_roots = [r for root in roots for r in (root, root.translate(s01))]
  stats = {}
  for i, j in itertools.combinations(range(len(pos_neg_roots)), 2):
    ri = pos_neg_roots[i]
    rj = pos_neg_roots[j]
    dist = sum(a != b for a, b in zip(ri, rj))
    stats[dist] = 1 + stats.get(dist, 0)
  return sorted(stats.items())


def do_validate_claim3():
  """Validates Claim #3."""
  print('\n\n### C#3: Validating the (8,4,4)-from-E8-roots-via-SL(2)x7 claim.'
        ' ###\n\n')
  violations = set()
  for num_sol, roots in enumerate(commuting_sl2_root_collections()):
    dists = hamming_distances(roots)
    # In the (8, 4, 4) Hamming code, we have 8 pairs of complementary words,
    # and each other pair has distance 4.
    h844_dists = [(4, 112), (8, 8)]
    is_hamming = dists == h844_dists
    if not is_hamming: violations.add(num_sol)
    print(f'N={num_sol}, distances={dists}, hamming={is_hamming}')
  if not violations:
    print('Claim 3 holds: All choices of root-sets give (8, 4, 4)-codes.')
  else:
    print('Claim 3 violated.')

#@title Code for claims 5,6

def check_so8c_limit(omega=0.0, r=2.0,
                     num_spot_checks=20,
                     seed=0,
                     scale=0.2, threshold=0.01):
  """Checks that the SO(8)c potential can be found as a limit of SO(8)xSO(8)."""
  s88 = numpy.cos(2 * omega) * r  # Spinors
  c88 = numpy.sin(2 * omega) * r  # Co-spinors
  tf_pot78c, tf_stat78c = get_tf_pot78c_stat78c(s88=s88, c88=c88)
  del tf_stat78c  # Unused here, named for documentation only.
  random_v70s = mu.rng(seed).normal(size=[num_spot_checks, 70], scale=scale)
  max_rel_delta = float('-inf')
  for rv70 in random_v70s:
    pot7c, stat7c = sugra7c.potential_and_stationarity(
        rv70 * (-.5), t_omega=mu.tff64(omega))
    pot78c = tf_pot78c(mu.tff64(rv70)).numpy()
    rel_delta = abs((pot78c - pot7c) / pot7c)
    max_rel_delta = max(max_rel_delta, rel_delta)
    print(
        f'V_so8c = {pot7c:+15.10f}, V_so8xso8 = {pot78c:+15.10f}, '
        f'rel_delta = {rel_delta:.6f}')
  if max_rel_delta < threshold:
    print('Check succeeded.')


def do_validate_claim5():
  """Validates Claim #5."""
  print('\n\n ### C#5: Validating omega=0 correspondence. ###\n\n')
  check_so8c_limit(omega=0, r=3.5, num_spot_checks=20, threshold=0.001)


def do_validate_claim6():
  """Validates Claim #6."""
  print('\n\n### C#6: Validating omega!=0 correspondence. ###\n\n')
  for omega in (-5.432, 0.035, 0.125):
    check_so8c_limit(omega=omega, r=3.5, num_spot_checks=20, threshold=0.001)

#@title Validating Claims

validate_claim_1 = True #@param {type:"boolean"}
validate_claim_2 = True #@param {type:"boolean"}
validate_claim_3 = True #@param {type:"boolean"}
validate_claim_4 = True #@param {type:"boolean"}
validate_claim_5 = True #@param {type:"boolean"}
validate_claim_6 = True #@param {type:"boolean"}

if validate_claim_1: do_validate_claim1()
if validate_claim_2: do_validate_claim2()
if validate_claim_3: do_validate_claim3()
if validate_claim_4: do_validate_claim4()
if validate_claim_5: do_validate_claim5()
if validate_claim_6: do_validate_claim6()

"""The code used above to validate claims of the paper depends on a collection of library definitions that have been embedded into this colab in not-human-readable form. Since they are relevant for properly checking the correctness of all claims, running the following cell with download a ZIP archive with all the relevant library definitions."""

#@title Download Library Code as a .ZIP (for local inspection)

def _download_zip(zipname='m_theory_library.zip'):
  import subprocess
  from google.colab import files
  try:
    os.unlink(zipname)
  except OSError:
    pass
  subprocess.run(['zip', '-9', '-r', zipname, 'm_theory', '-x', '*.pyc'])
  files.download(zipname)


_download_zip()